home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpat2-1.000 / xpat2-1 / xpat2-1.04 / src / X-events.c < prev    next >
C/C++ Source or Header  |  1995-11-25  |  9KB  |  333 lines

  1. /*****************************************************************************/
  2. /*                                         */
  3. /*                                         */
  4. /*    X patience version 2 -- module X-events.c                 */
  5. /*                                         */
  6. /*    Event handlers for the X interface                     */
  7. /*    written by Heiko Eissfeldt and Michael Bischoff                 */
  8. /*    see COPYRIGHT.xpat2 for Copyright details                 */
  9. /*                                         */
  10. /*                                         */
  11. /*****************************************************************************/
  12. #include "X-pat.h"
  13.  
  14. Display *dpy;
  15. int screen;
  16. unsigned long blackpixel;
  17. unsigned long whitepixel;
  18. GC blackgc;
  19. GC whitegc;
  20.  
  21. #ifdef useXlib
  22. static int intersect(int x1, int w1, int x2, int w2) {
  23.     if (x1 < x2)
  24.     return x1+w1 > x2;
  25.     else
  26.     return x2+w2 > x1;
  27. }
  28. #endif
  29.  
  30. /* events for Xlib AND Xaw interface */
  31. /* event entry points are: key_press, button_press, button_release,
  32.    mouse_motion (only called with button 3 pressed) redraw_table */
  33.  
  34.  
  35. void key_press(XKeyPressedEvent *xev) {
  36.     char str[32];
  37.     int num;
  38.  
  39. #define    get_name_field()    get_selection()
  40.  
  41.     num = XLookupString(xev, str, 31, NULL, NULL);
  42.     if (num == 0)
  43.     return;
  44.     str[num] = '\0';        /* NULL to terminate it */
  45.  
  46.     show_exposed_card(False);
  47.     key_pressed(str);
  48. }
  49.  
  50. /* SPEEDUP does not work yet */
  51. #ifdef SPEEDUP
  52. static int pile_is_drawn[MAXPILES] = { 0, 0 };
  53. static int buttons_are_drawn = 0;
  54. #endif
  55.  
  56. extern int table_clear;
  57.  
  58. void redraw_table(XExposeEvent *xev) {
  59.     int i;
  60.     table_clear = 0;
  61. #ifdef useXlib
  62.     if (intersect(0, graphic.buttons_height, xev->y, xev->height))
  63. #ifdef SPEEDUP
  64.     if (!buttons_are_drawn++)
  65. #endif
  66.         redraw_buttons(xev->x, xev->y, xev->width, xev->height, table, button.num, button.b);
  67.     if (intersect(graphic.buttons_height, graphic.message_height, xev->y, xev->height))
  68.     show_message(NULL);
  69.     if (xev->count && xev->y + xev->height < graphic.yoff)    /* else may miss the last event */
  70.     return;
  71. #endif
  72.  
  73. #ifdef LABER
  74.     printf("request for expose %d,%d of size %d,%d, cnt %d\n", xev->x, xev->y, xev->width, xev->height, xev->count);
  75. #endif
  76.  
  77.     for (i = 0; i < game.numpiles; ++i) {
  78.     struct pile *p;
  79. #ifdef SPEEDUP
  80.     if (pile_is_drawn[i]++)
  81.         continue;
  82. #endif
  83.     p = graphic.pile + i;
  84.     if (NOT_DISPLAYED(p) ||
  85.         xev->y >= p->y + p->ytotal || xev->y + xev->height <= p->y ||
  86.         xev->x >= p->x + p->xtotal || xev->x + xev->width <= p->x)
  87.         continue;    /* this pile is not affected */
  88. #ifdef LABER
  89.     printf("request for update pile %d of pos %d,%d, size %d,%d\n", i,
  90.            p->x, p->y, p->xtotal, p->ytotal);
  91. #endif
  92.     draw_pileupdate(i, 0);
  93.     }
  94.     if (!xev->count) {
  95.     show_arrow(2);                /* Update hint arrow */
  96.     }
  97. #ifdef LABER
  98.     if (!xev->count)
  99.     printf("         => last expose-table call\n");
  100. #endif
  101. #ifdef SPEEDUP
  102.     if (xev->count)
  103.     return;
  104.     /* was last event, unmark piles */
  105.     for (i = 0; i < MAXPILES; ++i)
  106.     pile_is_drawn[i] = 0;
  107.     buttons_are_drawn = 0;
  108. #endif
  109. }
  110.  
  111.  
  112. /* the pointer is somewhere in the area of pile i */
  113. /* check, if a card has to be exposed */
  114.  
  115. static void expose_card(Pileindex i, int y) {
  116.     struct pile *p;
  117.     Cardindex ind;
  118.  
  119.     if (EMPTY(i))
  120.     return;
  121.     p = graphic.pile + i;
  122.     ind = game.ind[i];
  123.     while (ind != INDEX_OF_LAST_CARD(i) && y >=    p->y + graphic.cardy[ind+1])
  124.         ++ind;
  125.     if (ind == INDEX_OF_LAST_CARD(i))   /* the most bottom card don't has to */
  126.         ind = -1;                       /* be put on foreground */
  127.     if (graphic.zoomed_card != ind) {   /* change of state */
  128.     show_exposed_card(False);    /* hide it */
  129.         /* graphic.zoomed_card is now -1 */
  130.         if (ind >= 0) {
  131.           graphic.zoomed_card = ind;
  132.         show_exposed_card(True);
  133.         }
  134.     }
  135. }
  136.  
  137. void mouse_motion(XPointerMovedEvent *xev) {
  138.     Pileindex i;
  139.     /* find new pile */
  140.     for (i = FIRST_SLOT; i <= LAST_SLOT; ++i) {
  141.     struct pile *p;
  142.     p = graphic.pile+i;
  143.     if (xev->x >= p->x && xev->x < p->x + p->xmaxwidth &&
  144.         xev->y >= p->y && xev->y < p->y + p->ymaxheight) {
  145.         /* yeah, a slot is hit */
  146.         /* find out which card is the target */
  147.         expose_card(i, xev->y);
  148.         return;
  149.         }
  150.     }
  151.     /* pointer moved out of scope: */
  152.     show_exposed_card(False);
  153. }
  154.  
  155. void button_release(XButtonPressedEvent *xev) {
  156.     show_exposed_card(False);
  157. }
  158.  
  159. void button_press(XButtonPressedEvent *xev) {
  160.     Pileindex i;
  161.  
  162.     show_exposed_card(False);
  163. #ifdef useXlib
  164.     {    void (*func)(void);
  165.     func = check_button_list(button.b, button.num, xev); 
  166.  
  167.     /* check for hit button */
  168.     if (func) {
  169.         (*func)();
  170.         return;
  171.     }
  172.     }
  173. #endif
  174.  
  175.     for (i = 0; i < game.numpiles; ++i) {
  176.     struct pile *p;
  177.     p = graphic.pile+i;
  178.     if (NOT_DISPLAYED(p))
  179.         continue;
  180.     if (xev->x >= p->x && xev->x < p->x + p->xmaxwidth &&
  181.         xev->y >= p->y && xev->y < p->y + p->ymaxheight) {
  182.         Cardindex cardi;
  183.         if EMPTY(i)
  184.         cardi = -1;
  185.         else {
  186.         cardi = INDEX_OF_LAST_CARD(i);
  187.         if (game.piletype[i] == Slot)
  188.             /* possibly a different card */
  189.             while (cardi != INDEX_OF_FIRST_CARD(i) &&
  190.                graphic.cardy[cardi] > xev->y - graphic.pile[i].y)
  191.             --cardi;
  192.         }
  193.         switch (xev->button) {
  194.         case Button1:            /* quick move */
  195.         button_pressed(i, cardi, 1);
  196.         break;
  197.         case Button2:            /* select / deselect */
  198.         button_pressed(i, cardi, 2);
  199.         break;
  200.         case Button3:
  201. #ifdef BUTTON_3_DRAGS_CARD
  202.         button_pressed(i, cardi, 3);
  203. #else
  204. #ifndef useXview
  205.         if (game.piletype[i] == Slot)
  206.             expose_card(i, xev->y);
  207. #else
  208.         if (game.piletype[i] == Slot &&
  209.             xev->y < graphic.pile[i].y + graphic.cardy[cardi] +
  210.             CARD_HEIGHT)
  211.             expose_card(i, xev->y);
  212.         else
  213.         {
  214.             menu_show(cmenu, canvas, bp_event, 0);
  215.             return;
  216.         }
  217. #endif
  218.         break;
  219. #endif
  220.         }
  221.         return;
  222.     }
  223.     }
  224. #ifdef useXview
  225.     if (xev->button == Button3)
  226.     {
  227.     menu_show(cmenu, canvas, bp_event, 0);
  228.     return;
  229.     }
  230. #endif
  231.     button_pressed(-1, -1, -1);        /* cancel action */
  232. }
  233.  
  234. /*****************************************************************************/
  235. /*                                         */
  236. /*    Functions for resize events and resize requests                 */
  237. /*                                         */
  238. /*****************************************************************************/
  239.  
  240. /* 1) hard resizes (i.e. forcing the outer window to change size) */
  241. /*    I think these are not liked in the Xaw community */
  242.  
  243. void cmd_MinWindow(void) {
  244.     XSize_t w, h;
  245.     w = graphic.min_width;
  246.     h = graphic.min_height;
  247.     Force_Resize(w, h);
  248. }
  249.  
  250. void cmd_PreferredWindow(void) {
  251.     XSize_t w, h;
  252.     w = graphic.preferred_width;
  253.     h = graphic.preferred_height;
  254.     Force_Resize(w, h);
  255. }
  256.  
  257. /* event handler function. This function is called by the Widget in response
  258.    to a request from us. In Xaw, this is a resize of the logical area, i.e.
  259.    of the virtual size of the tableau. */
  260.  
  261. void resize_event(XSize_t w, XSize_t h) {
  262. #ifdef LABER
  263.     printf("resize event to (%d,%d) called\n", w, h);
  264. #endif
  265.     if (game.graphic)
  266.     cmd_ResetHints();
  267.     if (graphic.height == h && graphic.width == w)
  268.     return;        /* no change of size */
  269.  
  270.     /* in xlib, we must clear the new area by hand; there may be illegal data
  271.        left in the server. This applies to Xaw as well */
  272.     {   XExposeEvent xev;
  273.     xev.count = -1;
  274.         if (game.graphic) {
  275.         if (graphic.height < h) {
  276.         /* window is greater now */
  277.         XClearArea(dpy, table, 0, graphic.height, graphic.width, h - graphic.height, True);
  278.         ++xev.count;
  279.         }
  280.         if (graphic.width < w) {
  281.         /* window is greater now */
  282.         XClearArea(dpy, table, graphic.width, 0, w - graphic.width, h, True);
  283.         ++xev.count;
  284.         }
  285.         if (xev.count >= 0) {
  286.         /* generate synthetic expose events for the new area */
  287.         /* this must be done before we possibly change the layout */
  288.         if (graphic.height < h) {
  289.             /* window is greater now */
  290.             xev.x = 0;
  291.             xev.y = graphic.height;
  292.             xev.width = graphic.width;
  293.             xev.height = h - graphic.height;
  294.             redraw_table(&xev);
  295.             --xev.count;
  296.         }
  297.         if (graphic.width < w) {
  298.             /* window is greater now */
  299.             xev.x = graphic.width;
  300.             xev.y = 0;
  301.             xev.width = w - graphic.width;
  302.             xev.height = h;
  303.             redraw_table(&xev);
  304.         }
  305.         }
  306.     }
  307.     }
  308.     graphic.height = h;
  309.     graphic.width = w;
  310.  
  311.     if (!game.graphic)
  312.     return;
  313. #ifdef useXlib
  314.     confirm.x = (graphic.width - confirm.w) / 2;
  315.     confirm.y = (graphic.height - confirm.h) / 2;
  316.     XMoveWindow(dpy, confirm.win, confirm.x, confirm.y);
  317. #endif
  318.  
  319.     if (graphic.autolayout) {
  320.     cmd_Layout();    /* change everything */
  321.     } else {
  322.     Pileindex i;
  323.     /* fix piles    THIS IS WRONG FOR 2-ROW LAYOUTS!!!! FIX THIS! */
  324.     for (i = 0; i < rules.numslots; ++i)
  325.         graphic.pile[SLOT(i)].ymaxheight = graphic.height - graphic.pile[SLOT(i)].y;
  326.     
  327.     for (i = FIRST_SLOT; i <= LAST_SLOT; ++i)
  328.         if (pile_resize(i))
  329.         draw_pileupdate(i, 0);
  330.     }
  331.     
  332. }
  333.